<template>
  <label :class="wrapClasses">
    <span :class="checkboxClasses">
      <span :class="innerClasses"></span>
      <input
        type="checkbox"
        :class="inputClasses"
        :disabled="disabled"
        :checked="currentValue"
        :tabIndex="field.tabIndex || null"
        @mousedown="mousedown"
        @focus="focus"
        @blur="blur"
        @change="change">
    </span>
    <span :class="labelClasses" v-if="label" v-html="label"></span>
  </label>
</template>
<script>
  import _ from 'lodash'

  const prefixCls = 'va-df-checkbox'

  /*
  * field配置
  *   trueValue
  *   falseValue
  *   label: string
  *   trueLabel: string
  *   falseLabel: string
  *   tabIndex: int
  *   disabled
  * */
  export default {
    props: {
      value: {
        default: false
      },
      disabled: {
        type: Boolean,
        default: false
      },
      field: {
        default () {
          return {}
        }
      }
    },
    data () {
      return {
        focused: false,
        currentValue: this.value === this.trueValue
      }
    },
    computed: {
      wrapClasses () {
        return [
          `${prefixCls}-wrapper`,
          {
            [`${prefixCls}-group-item`]: this.group,
            [`${prefixCls}-wrapper-checked`]: this.currentValue,
            [`${prefixCls}-wrapper-disabled`]: this.disabled,
            [`${prefixCls}-${this.size}`]: !!this.size
          }
        ]
      },
      checkboxClasses () {
        return [
          `${prefixCls}`,
          {
            [`${prefixCls}-checked`]: this.currentValue,
            [`${prefixCls}-disabled`]: this.disabled,
            [`${prefixCls}-indeterminate`]: this.indeterminate
          }
        ]
      },
      innerClasses () {
        return [
          `${prefixCls}-inner`,
          {
            focus: this.focused
          }
        ]
      },
      inputClasses () {
        return `${prefixCls}-input`
      },
      labelClasses () {
        return `${prefixCls}-label`
      },
      trueValue () {
        return this.field.trueValue === undefined ? true : this.field.trueValue
      },
      falseValue () {
        return this.field.falseValue === undefined ? false : this.field.falseValue
      },
      label () {
        return (this.value === this.trueValue ? this.field.trueLabel : this.field.falseLabel) || this.field.label
      }
    },
    mounted () {
      this.updateModel()
    },
    methods: {
      mousedown (evt) {
        if (+this.field.tabIndex === -1) {
          evt.preventDefault()
        }
      },
      focus () {
        this.focused = true
      },
      blur () {
        this.focused = false
      },
      change () {
        if (this.disabled) {
          return false
        }

        let value = !this.currentValue ? this.trueValue : this.falseValue
        this.$emit('input', value)
      },
      updateModel () {
        this.currentValue = this.value === this.trueValue
        if (_.isNil(this.value) && this.value !== this.trueValue && this.value !== this.falseValue) {
          this.$emit('input', this.falseValue)
        }
      }
    },
    watch: {
      value () {
        this.updateModel()
      }
    }
  }
</script>
